package com.hundsun.cprs.yyt.util;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 
 * @author linbo
 * @version $Id: CopyUtil.java,v 0.1 2011-10-19 下午3:19:44 suwei Exp $
 * @param <E>
 */

public class CopyUtil {
    protected final Log    log          = LogFactory.getLog(this.getClass());
    public static String   DATE_FORMAT  = "yyyy-MM-dd";
    public static String[] TYPE_SIMPLE  = { "java.lang.Integer", "int", "java.util.Date",
            "java.lang.Long"           };
    public static String   TYPE_INTEGER = "java.lang.Integer,int";
    public static String   TYPE_DATE    = "java.util.Date";
    public static String   TYPE_LONG    = "java.lang.Long";
    public static String   TYPE_DOUBLE  = "java.lang.Float";

    public static void copyProperties(Object source, Object target) {
        try {
            // 获取目标类的属性信息
            BeanInfo targetbean = Introspector.getBeanInfo(target.getClass());
            PropertyDescriptor[] propertyDescriptors = targetbean.getPropertyDescriptors();
            // 对每个目标类的属性查找set方法，并进行处理
            for (int i = 0; i < propertyDescriptors.length; i++) {
                PropertyDescriptor pro = propertyDescriptors[i];
                Method wm = pro.getWriteMethod();
                if (wm != null) {// 当目标类的属性具有set方法时，查找源类中是否有相同属性的get方法
                    BeanInfo sourceBean = Introspector.getBeanInfo(source.getClass());
                    PropertyDescriptor[] sourcepds = sourceBean.getPropertyDescriptors();
                    for (int j = 0; j < sourcepds.length; j++) {
                        if (sourcepds[j].getName().equals(pro.getName())) { // 匹配
                            Method rm = sourcepds[j].getReadMethod();
                            // 如果方法不可访问(get方法是私有的或不可达),则抛出SecurityException
                            if (!Modifier.isPublic(rm.getDeclaringClass().getModifiers())) {
                                rm.setAccessible(true);
                            }
                            // 获取对应属性get所得到的值
                            Object value = rm.invoke(source, new Object[0]);
                            if (!Modifier.isPublic(wm.getDeclaringClass().getModifiers())) {
                                wm.setAccessible(true);
                            }
                            // 调用目标类对应属性的set方法对该属性进行填充
                            wm.invoke((Object) target, new Object[] { value });
                            break;
                        }
                    }
                }
            }
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断是否是简单数据类型
     * 
     * @param String type
     */
    public static boolean isSimpleType(String type) {
        for (int i = 0; i < TYPE_SIMPLE.length; i++) {
            if (type.equals(TYPE_SIMPLE[i])) {
                return true;
            }
        }
        return false;
    }

    /**
     * 把String类型转换为Integer
     * 
     * @param String str
     * @return Integer
     */
    public static Integer parseInteger(String str) {
        if (str == null || str.equals("")) {
            return 0;
        } else {
            return Integer.parseInt(str);
        }
    }

    /**
     * 把String类型转换为Long
     * 
     * @param String str
     * @return Integer
     */
    public static Long parseLong(String str) {
        if (str == null || str.equals("")) {
            return (long) 0;
        } else {
            return Long.parseLong(str);
        }
    }

    /**
     * 把String类型转换为Date
     * 
     * @param String str
     * @return Date
     * @throws ParseException
     */
    public static Date parseDate(String str) throws ParseException {
        if (str == null || str.equals("")) {
            return null;
        } else {
            SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
            Date date = null;
            try {
                date = sdf.parse(str);
            } catch (java.text.ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }

    /**
     * 转换对象（用户定义的对象）。设置对象的Id。
     * 
     * @param Class clazz
     * @param  String str
     * @return Object
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     * @throws NoSuchMethodException 
     * @throws SecurityException 
     * @throws InvocationTargetException 
     * @throws IllegalArgumentException 
     * @throws ParseException
     */

    
    public static Object parseObject(Class clazz, String str) throws InstantiationException,
                                                             IllegalAccessException,
                                                             SecurityException,
                                                             NoSuchMethodException,
                                                             IllegalArgumentException,
                                                             InvocationTargetException {
        Object obj;
        if (str == null || str.equals("")) {
            obj = null;
        } else {
            obj = clazz.newInstance();
            Method m = clazz.getMethod("setId", str.getClass());
            m.invoke(obj, str);
        }
        return obj;
    }

    /**
     * 根据类型进行转换
     * 
     * @param Class clazz
     * @param String str
     * @return Object
     * @throws ParseException
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     * @throws InvocationTargetException 
     * @throws NoSuchMethodException 
     * @throws IllegalArgumentException 
     * @throws SecurityException 
     */
    
    public static Object parseByType(Class clazz, String str) throws ParseException,
                                                             InstantiationException,
                                                             IllegalAccessException,
                                                             SecurityException,
                                                             IllegalArgumentException,
                                                             NoSuchMethodException,
                                                             InvocationTargetException {
        Object r = "";
        String clazzName = splitSpace(clazz.getName());
        if (isSimpleType(clazzName)) {
            if (TYPE_INTEGER.contains(clazzName)) {
                r = parseInteger(str);
            } else if (TYPE_DATE.contains(clazzName)) {
                r = parseDate(str);
            } else if (TYPE_LONG.contains(clazzName)) {
                r = parseLong(str);
            }
        } else {
            r = parseObject(clazz, str);
        }
        return r;
    }

    /** 实现将源类(Map类型)属性拷贝到目标类中
       * @param Map map 
       * @param Object obj
       */
    
    public static void copyProperties(Map map, Object obj) throws Exception {
        // 获取目标类的属性信息
        BeanInfo targetbean = Introspector.getBeanInfo(obj.getClass());
        PropertyDescriptor[] propertyDescriptors = targetbean.getPropertyDescriptors();
        // 对每个目标类的属性查找set方法，并进行处理
        for (int i = 0; i < propertyDescriptors.length; i++) {
            PropertyDescriptor pro = propertyDescriptors[i];
            Method wm = pro.getWriteMethod();
            if (wm != null) {
                Iterator ite = map.keySet().iterator();
                while (ite.hasNext()) {
                    String key = (String) ite.next();
                    // 判断匹配
                    if (key.toLowerCase().equals(pro.getName().toLowerCase())) {
                        if (!Modifier.isPublic(wm.getDeclaringClass().getModifiers())) {
                            wm.setAccessible(true);
                        }
                        Object value = map.get(key);
                        String pt = splitSpace(pro.getPropertyType().getName());
                        //判断类型是否匹配，不匹配则作强制转换
                        if (!(pt.equals(value.getClass().getName()))) {
                            value = parseByType(pro.getPropertyType(), value.toString());
                        }
                        // 调用目标类对应属性的set方法对该属性进行填充
                        wm.invoke((Object) obj, new Object[] { value });
                        break;
                    }
                }
            }
        }
    }

    /**
     * 得到空格之后的字符
     * 
     * @param String type
     * @param String str
     * @return Date
     * @throws ParseException
     */
    public static String splitSpace(String str) throws ParseException {
        if (str.contains(" ")) {
            return str.split(" ")[1];
        } else {
            return str;
        }
    }

    
    public static void main(String[] args) throws SecurityException, NoSuchFieldException,
                                          IllegalArgumentException, IllegalAccessException {
        Field c = CopyUtil.class.getField("list");
        Field f = Field.class.getDeclaredField("signature");
        f.setAccessible(true);
        System.out.println(((String) f.get(c)));

        ParameterizedType pt = (ParameterizedType) CopyUtil.class.getField("list").getGenericType();
        Class classz = (Class) pt.getActualTypeArguments()[0];
        System.out.println(pt.getActualTypeArguments());
        System.out.println(pt.getActualTypeArguments().length);
        System.out.println(classz);

    }

    /* public static ProjectListing convertProjectListingDTO2ProjectListing(
                                                                          ProjectListingDTO projectListingDTO) {
         ProjectListing projectListing = new ProjectListing();
         projectListing.setId(projectListingDTO.getId());
         projectListing.setTitle(projectListingDTO.getTitle());
         projectListing.setCode(projectListingDTO.getCode());
         projectListing.setUserId(projectListingDTO.getUserId());
         projectListing.setUserAccount(projectListingDTO.getUserAccount());
         projectListing.setFundAccount(projectListingDTO.getFundAccount());
         projectListing.setListingType(projectListingDTO.getListingType());
         projectListing.setMeasureUnit(projectListingDTO.getMeasureUnit());
         projectListing.setQuantity(projectListingDTO.getQuantity());
         projectListing.setValuationUnit(projectListingDTO.getValuationUnit());
         projectListing.setListingPrice(projectListingDTO.getListingPrice());
         projectListing.setMultipleBase(projectListingDTO.getMultipleBase());
         projectListing.setMaxQuantity(projectListingDTO.getMaxQuantity());
         projectListing.setMinQuantity(projectListingDTO.getMinQuantity());
         projectListing.setRetail(projectListingDTO.getRetail());
         projectListing.setProjectTypeCode(projectListingDTO.getProjectTypeCode());
         projectListing.setBreedStandard(projectListingDTO.getBreedStandard());
         projectListing.setTradingType(projectListingDTO.getTradingType());
         projectListing.setDeliveryDate(projectListingDTO.getDeliveryDate());
         projectListing.setDeliveryPlace(projectListingDTO.getDeliveryPlace());
         projectListing.setDeliveryType(projectListingDTO.getDeliveryType());
         projectListing.setPaymentType(projectListingDTO.getPaymentType());
         projectListing.setListingStartTime(projectListingDTO.getListingStartTime());
         projectListing.setListingEndTime(projectListingDTO.getListingEndTime());
         projectListing.setInvoice(projectListingDTO.getInvoice());
         projectListing.setStatus(projectListingDTO.getStatus());
         projectListing.setProcessAuditNodes(projectListingDTO.getProcessAuditNodes());
         projectListing.setAuditNode(projectListingDTO.getAuditNode());
         projectListing.setCreator(projectListingDTO.getCreator());
         projectListing.setCreatorType(projectListingDTO.getCreatorType());
         projectListing.setOperator(projectListingDTO.getOperator());
         projectListing.setGmtCreate(projectListingDTO.getGmtCreate());
         projectListing.setGmtModify(projectListingDTO.getGmtModify());
         projectListing.setDeposit(projectListingDTO.getDeposit());
         projectListing.setProvince(projectListingDTO.getProvince());
         projectListing.setCity(projectListingDTO.getCity());
         projectListing.setArea(projectListingDTO.getArea());
         projectListing.setAddress(projectListingDTO.getAddress());
         projectListing.setLinkMan(projectListingDTO.getLinkMan());
         projectListing.setZipCode(projectListingDTO.getZipCode());
         projectListing.setPhone(projectListingDTO.getPhone());
         projectListing.setStorehouse(projectListingDTO.getStorehouse());

         projectListing.setPicturePath(projectListingDTO.getPicturePath());
         projectListing.setPicturePath1(projectListingDTO.getPicturePath1());
         projectListing.setPicturePath2(projectListingDTO.getPicturePath2());
         projectListing.setPicturePath3(projectListingDTO.getPicturePath3());
         projectListing.setPicturePath4(projectListingDTO.getPicturePath4());
         projectListing.setBreedStandardId(projectListingDTO.getBreedStandardId());
         projectListing.setDescription(projectListingDTO.getDescription());
         return projectListing;
     }*/
}
